package com.yonyou.pmclouds.completedcollate.rmiimpl;

import com.alibaba.dubbo.config.annotation.Service;
import com.yonyou.pmclouds.ApplicationConsts;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoInsertProcessor;
import com.yonyou.pmclouds.basecom.bp.processor.AuditInfoUpdateProcessor;
import com.yonyou.pmclouds.basecom.bp.template.MultiInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleDeleteBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleInsertBpTemplate;
import com.yonyou.pmclouds.basecom.bp.template.SingleUpdateBpTemplate;
import com.yonyou.pmclouds.basecom.exception.BusinessException;
import com.yonyou.pmclouds.basecom.exception.ConcurrentOperationException;
import com.yonyou.pmclouds.basecom.lock.AutoReleaseLockUtil;
import com.yonyou.pmclouds.basecom.runtime.RuntimeEnvironment;
import com.yonyou.pmclouds.completedcollate.entity.CompletedCollateBVO;
import com.yonyou.pmclouds.completedcollate.entity.CompletedCollateContentVO;
import com.yonyou.pmclouds.completedcollate.entity.CompletedCollateVO;
import com.yonyou.pmclouds.completedcollate.mapper.CompletedCollateBVOMapper;
import com.yonyou.pmclouds.completedcollate.mapper.CompletedCollateContentVOMapper;
import com.yonyou.pmclouds.completedcollate.mapper.CompletedCollateVOMapper;
import com.yonyou.pmclouds.completedcollate.processor.CompletedCollateNameCheck;
import com.yonyou.pmclouds.completedcollate.rmiitf.CompletedCollateMaintain;
import com.yonyou.pmclouds.project.entity.ProjectVO;
import com.yonyou.pmclouds.project.rmiitf.ProjectSimpleQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * 竣工资料整理数据操作接口实现
 *
 * @author yzx
 * @Date: 2018/5/23 15:31
 */
@Service(version = ApplicationConsts.APPLICATION_VERSION, interfaceClass = CompletedCollateMaintain.class)
public class CompletedCollateMaintainImpl implements CompletedCollateMaintain {
    private static final String LOCK_PREFIX = "CompletedCollate_";
    private static final String[] HEAD_UPDATE_FIELDS = new String[]{CompletedCollateVO.PK_PROJECT, CompletedCollateVO.SNAME, CompletedCollateVO.CATALOG_NAME, CompletedCollateVO.PK_COMPLETEDCATALOG};
    @Autowired
    private CompletedCollateVOMapper collateVOMapper;
    @Autowired
    private CompletedCollateBVOMapper collateBVOMapper;
    @Autowired
    private CompletedCollateContentVOMapper collateContentVOMapper;
    @Autowired
    private ProjectSimpleQuery projectQuery;

    @Override
    public String insert(CompletedCollateVO collateVO) throws BusinessException {
        //  add lock
        if (!AutoReleaseLockUtil.addAutoReleaseLock(LOCK_PREFIX + collateVO.getPkTenant())) {
            throw new ConcurrentOperationException();
        }
        SingleInsertBpTemplate<CompletedCollateVO> bp = new SingleInsertBpTemplate<>(collateVOMapper);
        SingleInsertBpTemplate<CompletedCollateBVO> detailBp = new SingleInsertBpTemplate<>(collateBVOMapper);
        MultiInsertBpTemplate<CompletedCollateContentVO> contentBp = new MultiInsertBpTemplate<>(collateContentVOMapper);
        // 添加审计信息
        bp.addBeforeProcessor(new AuditInfoInsertProcessor<CompletedCollateVO>());
        // 名称重复性校验
        bp.addBeforeProcessor(new CompletedCollateNameCheck(collateVOMapper));
        bp.insert(collateVO);
        // 保存完主表后保存表体内容
        if (collateVO.getCollateBVOS() != null) {
            for (CompletedCollateBVO collateBVO : collateVO.getCollateBVOS()) {
                collateBVO.setPkCompletedCollate(collateVO.getPkCompletedCollate());
                // 添加审计信息
                detailBp.addBeforeProcessor(new AuditInfoInsertProcessor<CompletedCollateBVO>());
                detailBp.insert(collateBVO);
                // 表体关联单据内容保存或更新
                if (collateBVO.getContentVOS() != null && collateBVO.getContentVOS().length > 0) {
                    for (CompletedCollateContentVO contentVO : collateBVO.getContentVOS()) {
                        contentVO.setPkCompletedCollateB(collateBVO.getPkCompletedCollateB());
                    }
                    contentBp.insert(collateBVO.getContentVOS());
                }
            }
        }
        return collateVO.getPkCompletedCollate();
    }

    @Override
    public void deleteCollate(CompletedCollateVO collateVO) throws BusinessException {
        //  add lock
        if (!AutoReleaseLockUtil.addAutoReleaseLock(LOCK_PREFIX + RuntimeEnvironment.getTenantId())) {
            throw new ConcurrentOperationException();
        }
        checkAuth(collateVO); //权限校验
        SingleDeleteBpTemplate<CompletedCollateVO> bp = new SingleDeleteBpTemplate<>(collateVOMapper);
        bp.delete(collateVO);
    }

    @Override
    public String update(CompletedCollateVO collateVO) throws BusinessException {
        //  add lock
        if (!AutoReleaseLockUtil.addAutoReleaseLock(LOCK_PREFIX + collateVO.getPkTenant())) {
            throw new ConcurrentOperationException();
        }
        checkAuth(collateVO); //权限校验
        SingleUpdateBpTemplate<CompletedCollateVO> bp = new SingleUpdateBpTemplate<>(collateVOMapper, HEAD_UPDATE_FIELDS);
        SingleInsertBpTemplate<CompletedCollateBVO> detailBp = new SingleInsertBpTemplate<>(collateBVOMapper);
        SingleDeleteBpTemplate<CompletedCollateBVO> detailDelBp = new SingleDeleteBpTemplate<>(collateBVOMapper);
        SingleInsertBpTemplate<CompletedCollateContentVO> contentBp = new SingleInsertBpTemplate<>(collateContentVOMapper);
        SingleDeleteBpTemplate<CompletedCollateContentVO> delBp = new SingleDeleteBpTemplate<>(collateContentVOMapper);
        //审计信息
        bp.addBeforeProcessor(new AuditInfoUpdateProcessor<CompletedCollateVO>());
        // 名称重复性校验
        bp.addBeforeProcessor(new CompletedCollateNameCheck(collateVOMapper));
        bp.update(collateVO);
        // 保存完主表后保存表体内容
        if (collateVO.getCollateBVOS() != null) {
            // 收集表体主键
            Set<String> collateBPks = new HashSet<>();
            // 已经更换了目录，这时原始表体需要全部删除，然后重新插入现在的表体
            boolean isChangeCatalog = false;
            for (CompletedCollateBVO collateBVO : collateVO.getCollateBVOS()) {
                if (StringUtils.isEmpty(collateBVO.getPkCompletedCollateB())) {
                    isChangeCatalog = true;
                    break;
                }
                collateBPks.add(collateBVO.getPkCompletedCollateB());
            }
            // 如何改变了目录获取原来目录表体明细数据
            if (isChangeCatalog) {
                CompletedCollateBVO[] collateBVOS = collateBVOMapper.queryBVOsByPkCollate(collateVO.getPkCompletedCollate());
                for (CompletedCollateBVO collateBVO : collateBVOS) {
                    collateBPks.add(collateBVO.getPkCompletedCollateB());
                    detailDelBp.delete(collateBVO);
                }
            }
            // 根据表体主键，查出所有孙表内容数据
            List<CompletedCollateContentVO> oldContentVOS = collateContentVOMapper.queryByPkCollateBs(collateBPks.toArray(new String[collateBPks.size()]));
            for (CompletedCollateContentVO toDelVO : oldContentVOS) {
                delBp.delete(toDelVO);
            }
            for (CompletedCollateBVO collateBVO : collateVO.getCollateBVOS()) {
                if (isChangeCatalog) {
                    collateBVO.setPkCompletedCollate(collateVO.getPkCompletedCollate());
                    //审计信息
                    detailBp.addBeforeProcessor(new AuditInfoUpdateProcessor<CompletedCollateBVO>());
                    detailBp.insert(collateBVO);
                }
                // 表体关联单据内容保存
                if (collateBVO.getContentVOS() != null) {
                    for (CompletedCollateContentVO contentVO : collateBVO.getContentVOS()) {
                        contentVO.setPkCompletedCollateContent(null);
                        contentVO.setPkCompletedCollateB(collateBVO.getPkCompletedCollateB());
                        contentBp.insert(contentVO);
                    }
                }
            }
        }
        return collateVO.getPkCompletedCollate();
    }

    private void checkAuth(CompletedCollateVO vo) throws BusinessException {
        CompletedCollateVO collateVO = collateVOMapper.getById(vo.getPkCompletedCollate());

        ProjectVO projectVO = projectQuery.queryProject(collateVO.getPkProject());
        if(projectVO == null) throw new BusinessException("资料对应项目不存在");

        String loginUser = RuntimeEnvironment.getLoginUserId();
        if(!collateVO.getCreator().equals(loginUser) && !loginUser.equals(projectVO.getManager())){
            throw new BusinessException("无权限操作，非创建人或项目经理不可修改和删除！");
        }
    }
}
